package com.yenlien.traceyun.control.service;

import com.yenlien.traceyun.control.controller.form.FindStoreHouseDTO;
import com.yenlien.traceyun.control.dao.GoodsDao;
import com.yenlien.traceyun.control.dao.PositionDao;
import com.yenlien.traceyun.control.dao.ShelvesDao;
import com.yenlien.traceyun.control.dao.StoreHouseDao;
import com.yenlien.traceyun.control.entity.Goods;
import com.yenlien.traceyun.control.entity.Position;
import com.yenlien.traceyun.control.entity.Shelves;
import com.yenlien.traceyun.control.entity.StoreHouse;
import com.yenlien.traceyun.control.interceptor.UserAuthUtil;
import com.yenlien.traceyun.webase.exception.BusinessException;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import javax.transaction.Transactional;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author jialong
 * @date 2021/05/18
 * @description: 仓库服务
 **/
@Service
public class StoreHouseService {


    @Autowired
    private StoreHouseDao storeHouseDao;

    @Autowired
    private PositionDao positionDao;

    @Autowired
    private ShelvesDao shelvesDao;

    @Autowired
    private GoodsDao goodsDao;


    @Transactional
    public StoreHouse save(StoreHouse storeHouse) {
        // 计算该仓库下的气调仓位数量和容量以及干仓位数和干仓位容量
        List<Position> positionList = storeHouse.getPositionList();
        long airPositions = positionList.stream().filter(x -> "1".equals(x.getType())).count();
        storeHouse.setAirPositions(airPositions);
        storeHouse.setDryPositions(positionList.size() - airPositions);
        int airVolume = 0;
        int dryVolume = 0;
        for (Position position : positionList) {
            if ("1".equals(position.getType())) {
                airVolume += position.getVolume();
            } else if ("2".equals(position.getType())) {
                dryVolume += position.getVolume();
            }
        }
        storeHouse.setAirVolume(airVolume);
        storeHouse.setDryVolume(dryVolume);
        StoreHouse storeSaved = storeHouseDao.save(storeHouse);
        if (storeSaved.getId() == null) {
            throw new BusinessException("添加失败");
        }
        List<Shelves> shelvesList = new ArrayList<>();
        // 添加仓位
        for (Position position : positionList) {
            position.setStoreId(storeSaved.getId());
            Position positionSaved = positionDao.save(position);
            shelvesList = position.getShelvesList();
            // 对应图片和绑定仓位ID
            for (Shelves shelves : shelvesList) {
                shelves.setPositionId(positionSaved.getId());
//                for (MultipartFile file : files){
//                    if(file.getName().equals(shelves.getImg())){
//                        shelves.setImg(fileRestService.upload(file));
//                    }
//                }
            }
            // 保存货架
            shelvesDao.saveAll(shelvesList);
        }
        return storeSaved;
    }


    public Page<StoreHouse> findList(StoreHouse storeHouse) {
        Pageable pageable = PageRequest.of(storeHouse.getPage(), storeHouse.getPageSize(), Sort.Direction.ASC, ("createTime"));
        return storeHouseDao.findAll((Root<StoreHouse> root, CriteriaQuery<?> query, CriteriaBuilder cb) -> {
            //构造查询条件
            List<Predicate> list = new ArrayList<>();
            if (StringUtils.isNotBlank(storeHouse.getName())) {
                list.add(cb.like(root.get("name"), "%" + storeHouse.getName() + "%"));
            }
            if (StringUtils.isNotBlank(storeHouse.getAddress())) {
                list.add(cb.equal(root.get("address"), storeHouse.getAddress()));
            }
            if (storeHouse.getAirPositions() != null) {
                list.add(cb.equal(root.get("airPositions"), storeHouse.getAirPositions()));
            }
            if (storeHouse.getDryPositions() != null) {
                list.add(cb.equal(root.get("dryPositions"), storeHouse.getDryPositions()));
            }
            String companyId = UserAuthUtil.getLoginUser().getCompanyId();
            list.add(cb.equal(root.get("companyId"), companyId));
            Predicate[] predicate = new Predicate[list.size()];
            return cb.and(list.toArray(predicate));
        }, pageable);
    }


    public StoreHouse findById(Long id) {
        StoreHouse storeHouse = storeHouseDao.findById(id);
        List<Position> positionList = positionDao.findByStoreId(storeHouse.getId());
        for (Position position : positionList) {
            position.setShelvesList(shelvesDao.findByPositionId(position.getId()));
        }
        storeHouse.setPositionList(positionList);
        return storeHouse;
    }


    public List<StoreHouse> findChild(FindStoreHouseDTO findStoreHouseDTO) {
        List<StoreHouse> storeHouseList = new ArrayList<>();
        // 根据条件获取仓库
        if (StringUtils.isNotBlank(findStoreHouseDTO.getStoreHouseName())) {
            storeHouseList.add(storeHouseDao.findByNameAndCompanyId(findStoreHouseDTO.getStoreHouseName(), UserAuthUtil.getLoginUser().getCompanyId()));
        } else {
            storeHouseList.addAll(storeHouseDao.findByCompanyId(UserAuthUtil.getLoginUser().getCompanyId()));
        }
        if (storeHouseList.size() == 0) {
            return storeHouseList;
        }
        List<Long> storeIds = storeHouseList.stream().map(StoreHouse::getId).collect(Collectors.toList());

        // 根据条件获取仓库下的仓位
        List<Position> positions = new ArrayList<>();
        if (StringUtils.isNotBlank(findStoreHouseDTO.getPositionName())) {
            positions.addAll(positionDao.findByNameAndStoreIds(findStoreHouseDTO.getStoreHouseName(), storeIds));
        } else {
            positions.addAll(positionDao.findByStoreIds(storeIds));
        }
        if (positions.size() == 0) {
            return storeHouseList;
        }
        List<Long> positionIds = positions.stream().map(Position::getId).collect(Collectors.toList());

        // 根据条件获取货架
        List<Shelves> shelvesList = new ArrayList<>();
        if ("1".equals(findStoreHouseDTO.getType())) {
            shelvesList.addAll(shelvesDao.findByPositionIds(positionIds));
        } else if ("2".equals(findStoreHouseDTO.getType())) {
            shelvesList.addAll(shelvesDao.findShelvesGoods(positionIds));
        } else if ("3".equals(findStoreHouseDTO.getType())) {
            shelvesList.addAll(shelvesDao.findShelvesNoneGoods(positionIds));
        }
        if (shelvesList.size() == 0) {
            //  将仓库和仓位数据进行组装 在返回
            for (StoreHouse store : storeHouseList) {
                ArrayList<Position> positionList = new ArrayList<>();
                for (Position position : positions) {
                    if (store.getId() == position.getId()) {
                        positionList.add(position);
                    }
                }
                store.setPositionList(positionList);
            }
            return storeHouseList;
        }
        //
        List<Goods> goodsList = goodsDao.getGoodsByShelvesId(shelvesList.stream().map(Shelves::getId).collect(Collectors.toList()));

        // 组装 货架对应的货物 仓位 仓库
        for (StoreHouse store : storeHouseList) {
            ArrayList<Position> positionList = new ArrayList<>();
            for (Position position : positions) {
                if (store.getId() == position.getStoreId()) {
                    positionList.add(position);
                }
                List<Shelves> shelvesArrayList = new ArrayList<>();
                for (Shelves shelves : shelvesList) {
                    if (shelves.getPositionId() == position.getId()) {
                        shelvesArrayList.add(shelves);
                    }
                    for (Goods goods : goodsList) {
                        if (goods.getShelvesId() == shelves.getId()) {
                            shelves.setGoods(goods);
                        }
                    }
                    if (shelves.getGoods() == null) {
                        shelves.setState("入库");
                    } else {
                        shelves.setState("出库");
                    }
                }
                position.setShelvesList(shelvesArrayList);
            }
            store.setPositionList(positionList);
        }
        return storeHouseList;
    }
}
